#ifndef THRUMASTERPUSHER_H
#define THRUMASTERPUSHER_H

#include <hidapi.h>
#include <QObject>
#include <QThread>

class ThrumasterPusher : public QObject
{
    Q_OBJECT
    Q_PROPERTY(ButtonState button1 READ button1 WRITE setButton1 NOTIFY button1Changed FINAL)
    Q_PROPERTY(ButtonState button2 READ button2 WRITE setButton2 NOTIFY button2Changed FINAL)
    Q_PROPERTY(ButtonState button3 READ button3 WRITE setButton3 NOTIFY button3Changed FINAL)
    Q_PROPERTY(Switcher2State switcher21 READ switcher21 WRITE setSwitcher21 NOTIFY switcher21Changed FINAL)
    Q_PROPERTY(Switcher2State switcher22 READ switcher22 WRITE setSwitcher22 NOTIFY switcher22Changed FINAL)
    Q_PROPERTY(Switcher2State switcher23 READ switcher23 WRITE setSwitcher23 NOTIFY switcher23Changed FINAL)
    Q_PROPERTY(Switcher2State switcher24 READ switcher24 WRITE setSwitcher24 NOTIFY switcher24Changed FINAL)
    Q_PROPERTY(Switcher2State switcher25 READ switcher25 WRITE setSwitcher25 NOTIFY switcher25Changed FINAL)
    Q_PROPERTY(Switcher3State switcher31 READ switcher31 WRITE setSwitcher31 NOTIFY switcher31Changed FINAL)
    Q_PROPERTY(Switcher3State switcher32 READ switcher32 WRITE setSwitcher32 NOTIFY switcher32Changed FINAL)
    Q_PROPERTY(Switcher3State switcher33 READ switcher33 WRITE setSwitcher33 NOTIFY switcher33Changed FINAL)
    Q_PROPERTY(Switcher3State switcher34 READ switcher34 WRITE setSwitcher34 NOTIFY switcher34Changed FINAL)
    Q_PROPERTY(Switcher3State switcher35 READ switcher35 WRITE setSwitcher35 NOTIFY switcher35Changed FINAL)
    Q_PROPERTY(Switcher3State switcher36 READ switcher36 WRITE setSwitcher36 NOTIFY switcher36Changed FINAL)
    Q_PROPERTY(Switcher3State switcher37 READ switcher37 WRITE setSwitcher37 NOTIFY switcher37Changed FINAL)
    Q_PROPERTY(Switcher3State switcher38 READ switcher38 WRITE setSwitcher38 NOTIFY switcher38Changed FINAL)
    Q_PROPERTY(AxisState axis4 READ axis4 WRITE setAxis4 NOTIFY axis4Changed FINAL)
    Q_PROPERTY(AxisState axis8 READ axis8 WRITE setAxis8 NOTIFY axis8Changed FINAL)
    Q_PROPERTY(double slider READ slider WRITE setSlider NOTIFY sliderChanged FINAL)
    Q_PROPERTY(double axisSliderX READ axisSliderX WRITE setAxisSliderX NOTIFY axisSliderXChanged FINAL)
    Q_PROPERTY(double axisSliderY READ axisSliderY WRITE setAxisSliderY NOTIFY axisSliderYChanged FINAL)
    Q_PROPERTY(bool axisSliderPressed READ axisSliderPressed WRITE setAxisSliderPressed NOTIFY axisSliderPressedChanged FINAL)
    Q_PROPERTY(double pusher1 READ pusher1 WRITE setPusher1 NOTIFY pusher1Changed FINAL)
    Q_PROPERTY(double pusher2 READ pusher2 WRITE setPusher2 NOTIFY pusher2Changed FINAL)

public:
    enum AxisState {        // axis控件的状态
        Axis_RELEASE,
        Axis_UP,
        Axis_DOWN,
        Axis_LEFT,
        Axis_RIGHT,
        Axis_LEFT_UP,
        Axis_LEFT_DOWN,
        Axis_RIGHT_UP,
        Axis_RIGHT_DOWN,
        Axis_PRESSED
    };
    Q_ENUM(AxisState)

    enum ButtonState {      // button控件的状态
        Button_RELEASE,
        Button_PUSHED
    };
    Q_ENUM(ButtonState)

    enum Switcher2State {   // 两状态开关
        Switcher2_OFF,
        Switcher2_ON
    };
    Q_ENUM(Switcher2State)

    enum Switcher3State {   // 三状态开关
        Switcher3_UP,
        Switcher3_MID,
        Switcher3_DOWN
    };
    Q_ENUM(Switcher3State)

public:
    explicit ThrumasterPusher(QObject *parent = nullptr);
    ~ThrumasterPusher();

    void readRawData();
    void stopReadData();

    ButtonState button1() const;
    void setButton1(ButtonState newButton21);

    ButtonState button2() const;
    void setButton2(ButtonState newButton22);

    ButtonState button3() const;
    void setButton3(ButtonState newButton23);

    Switcher2State switcher21() const;
    void setSwitcher21(Switcher2State newSwitcher21);

    Switcher2State switcher22() const;
    void setSwitcher22(Switcher2State newSwitcher22);

    Switcher2State switcher23() const;
    void setSwitcher23(Switcher2State newSwitcher23);

    Switcher2State switcher24() const;
    void setSwitcher24(Switcher2State newSwitcher24);

    Switcher2State switcher25() const;
    void setSwitcher25(Switcher2State newSwitcher25);

    Switcher3State switcher31() const;
    void setSwitcher31(Switcher3State newSwitcher31);

    Switcher3State switcher32() const;
    void setSwitcher32(Switcher3State newSwitcher32);

    Switcher3State switcher33() const;
    void setSwitcher33(Switcher3State newSwitcher33);

    Switcher3State switcher34() const;
    void setSwitcher34(Switcher3State newSwitcher34);

    Switcher3State switcher35() const;
    void setSwitcher35(Switcher3State newSwitcher35);

    Switcher3State switcher36() const;
    void setSwitcher36(Switcher3State newSwitcher36);

    Switcher3State switcher37() const;
    void setSwitcher37(Switcher3State newSwitcher37);

    Switcher3State switcher38() const;
    void setSwitcher38(Switcher3State newSwitcher38);

    AxisState axis8() const;
    void setAxis8(AxisState newAxis8);

    double axisSliderX() const;
    void setAxisSliderX(double newAxisSliderX);

    double axisSliderY() const;
    void setAxisSliderY(double newAxisSliderY);

    AxisState axis4() const;
    void setAxis4(AxisState newAxis4);

    bool axisSliderPressed() const;
    void setAxisSliderPressed(bool newAxisSliderPressed);

    double slider() const;
    void setSlider(double newSlider);

    double pusher1() const;
    void setPusher1(double newPusher1);

    double pusher2() const;
    void setPusher2(double newPusher2);
    bool isContinueReading;


private:
    void parseButtons(unsigned char data[], int n);
    void parseSwitcher2s(unsigned char data[], int n);
    void parseSwitcher3s(unsigned char data[], int n);
    void parseAxis4(unsigned char data[], int n);
    void parseAxis8(unsigned char data[], int n);
    void parseAxisSlider(unsigned char data[], int n);
    void parseSlider(unsigned char data[], int n);
    void parsePushers(unsigned char data[], int n);

signals:
    void button1Changed();

    void button2Changed();

    void button3Changed();

    void switcher21Changed();

    void switcher22Changed();

    void switcher23Changed();

    void switcher24Changed();

    void switcher25Changed();

    void switcher31Changed();

    void switcher32Changed();

    void switcher33Changed();

    void switcher34Changed();

    void switcher35Changed();

    void switcher36Changed();

    void switcher37Changed();

    void switcher38Changed();

    void axis8Changed();

    void axisSliderXChanged();

    void axisSliderYChanged();

    void axis4Changed();

    void axisSliderPressedChanged();

    void sliderChanged();

    void pusher1Changed();

    void pusher2Changed();

private:
    hid_device *device;

    ButtonState m_button1;
    ButtonState m_button2;
    ButtonState m_button3;
    Switcher2State m_switcher21;
    Switcher2State m_switcher22;
    Switcher2State m_switcher23;
    Switcher2State m_switcher24;
    Switcher2State m_switcher25;
    Switcher3State m_switcher31;
    Switcher3State m_switcher32;
    Switcher3State m_switcher33;
    Switcher3State m_switcher34;
    Switcher3State m_switcher35;
    Switcher3State m_switcher36;
    Switcher3State m_switcher37;
    Switcher3State m_switcher38;
    AxisState m_axis4;
    AxisState m_axis8;
    double m_axisSliderX;
    double m_axisSliderY;
    bool m_axiSliderPressed;
    bool m_axisSliderPressed;
    double m_slider;
    double m_pusher1;
    double m_pusher2;
};

class ThrumasterPusherThread: public QThread
{
    Q_OBJECT

public:
    explicit ThrumasterPusherThread(ThrumasterPusher* thrumasterPusher, QObject *parent = nullptr)
        : QThread(parent),m_thrumasterPusher(thrumasterPusher) {};

protected:
    void run() override {
        while(!isInterruptionRequested()) {
            m_thrumasterPusher->readRawData();
        }
    }

private:
    ThrumasterPusher* m_thrumasterPusher;
};

#endif // THRUMASTERPUSHER_H
